package tools

import (
	"context"
	"fmt"

	"github.com/mark3labs/mcp-go/mcp"
	"github.com/mark3labs/mcp-go/server"
)

type ArtifactLister interface {
	ListArtifacts(ctx context.Context, executionId string) (string, error)
}

func ListArtifacts(client ArtifactLister) (tool mcp.Tool, handler server.ToolHandlerFunc) {
	tool = mcp.NewTool("list_artifacts",
		mcp.WithDescription(ListArtifactsDescription),
		mcp.WithString("executionId", mcp.Required(), mcp.Description(ExecutionIdDescription)),
	)

	handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
		executionId, err := RequiredParam[string](request, "executionId")
		if err != nil {
			return mcp.NewToolResultError(err.Error()), nil
		}

		result, err := client.ListArtifacts(ctx, executionId)
		if err != nil {
			return mcp.NewToolResultError(fmt.Sprintf("Failed to list artifacts: %v", err)), nil
		}

		return mcp.NewToolResultText(result), nil
	}

	return tool, handler
}

const MaxLines = 100

type ArtifactReader interface {
	ReadArtifact(ctx context.Context, executionId, filename string) (string, error)
}

func ReadArtifact(client ArtifactReader) (tool mcp.Tool, handler server.ToolHandlerFunc) {
	tool = mcp.NewTool("read_artifact",
		mcp.WithDescription(ReadArtifactDescription),
		mcp.WithString("executionId", mcp.Required(), mcp.Description(ExecutionIdDescription)),
		mcp.WithString("fileName", mcp.Required(), mcp.Description(FilenameDescription)),
	)

	handler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
		executionId, err := RequiredParam[string](request, "executionId")
		if err != nil {
			return mcp.NewToolResultError(err.Error()), nil
		}

		fileName, err := RequiredParam[string](request, "fileName")
		if err != nil {
			return mcp.NewToolResultError(err.Error()), nil
		}

		content, err := client.ReadArtifact(ctx, executionId, fileName)
		if err != nil {
			return mcp.NewToolResultError(fmt.Sprintf("Error reading artifact: %v", err)), nil
		}

		if content == "" {
			return mcp.NewToolResultText(fmt.Sprintf("Artifact \"%s\" is empty or not found", fileName)), nil
		}

		// Limit content to max lines
		limitedContent := LimitContentToLines(content, MaxLines)
		return mcp.NewToolResultText(limitedContent), nil
	}

	return tool, handler
}
